package no.ntnu.item.ttm4115.termproject.discussionagent.gui;

/****************************************************************/
/*                      DiscussionAgentGUI                      */
/*                                                              */
/****************************************************************/
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;

import javax.swing.*;
import javax.swing.tree.*;

import com.thoughtworks.xstream.XStream;

import no.ntnu.item.ttm4115.termproject.ForwardDiscussionEdit;
import no.ntnu.item.ttm4115.termproject.ForwardDiscussionUpdate;
import no.ntnu.item.ttm4115.termproject.ReleasePlayerDiscussionAgent;
import no.ntnu.item.ttm4115.termproject.discussionagent.gui.Discussion;
import no.ntnu.item.ttm4115.termproject.discussionagent.gui.DiscussionDialog;
import no.ntnu.item.ttm4115.termproject.extrasagent.Group;
import no.ntnu.item.ttm4115.termproject.extrasagent.Player;
import no.ntnu.item.ttm4115.termproject.playeragent.gui.MeetingPlaceGUI;
import no.tellu.common.actorframe.ActorSM;
import no.tellu.common.javaframe.ActorAddress;
/**
 * Summary description for DiscussionGUI
 *
 */
public class DiscussionAgentGUI extends JPanel
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	// Variables declaration
	private javax.swing.JPanel jPanelDiscussion;
	private javax.swing.JScrollPane jScrollPaneDiscussion;
	private javax.swing.JTree jTreeDiscussion;
	private javax.swing.JButton closeButtonGrpDis;
    private javax.swing.JLabel jLabelExplain1;
    private javax.swing.JLabel jLabelExplain2;
    private javax.swing.JLabel jLabelGrpDis;
    private javax.swing.JLabel jLabelGrpDisInput;
	private ActorSM asm;
	private String playerName;
	private ActorAddress groupDiscussionAgentGroup;
	private TreeNode rootNode;
	private DefaultTreeModel jTreeDiscussionModel;
	private MeetingPlaceGUI mainFrame;
	private String groupName;
	{
		//Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	// End of variables declaration

	public DiscussionAgentGUI(ActorSM asm, String playerName, ActorAddress groupDiscussionAgentGroup, String groupName, MeetingPlaceGUI mainFrame)
	{
		this.asm = asm;
		this.playerName = playerName;
		this.groupDiscussionAgentGroup = groupDiscussionAgentGroup;
		this.groupName = groupName;
		this.mainFrame = mainFrame;
		this.mainFrame.getPane().addTab("Discussion: "+groupName, this);
		this.repaint();
        this.mainFrame.repaint();
		
		initComponents();
		
	}
	
	public void initComponents(){
		
		jLabelExplain1 = new JLabel();
		jLabelExplain2 = new JLabel();
		jLabelGrpDis = new JLabel();
		jLabelGrpDisInput = new JLabel();
		jScrollPaneDiscussion = new JScrollPane();
		closeButtonGrpDis = new JButton();
		jPanelDiscussion = new JPanel();
		rootNode = new DefaultMutableTreeNode(new Discussion("Discussions","0",null));
		jTreeDiscussionModel = new DefaultTreeModel(rootNode);

		
		jLabelGrpDis.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        jLabelGrpDis.setText("Group Discussion:");

        jLabelGrpDisInput.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        jLabelGrpDisInput.setText("N/A");

        jLabelExplain1.setText("Right click on the desired topic to add a comment");

        jLabelExplain2.setText("If you want to edit your own comment, simply right click on it, and choose edit");
        
		jTreeDiscussion = getJTreeGroupDiscussion();
		jTreeDiscussion.setEditable(false);
		jTreeDiscussion.setSelectionPath(new TreePath(rootNode));
        jTreeDiscussion.addMouseListener(
				new MouseAdapter() {
					public void mouseReleased( MouseEvent e ) {
						if ( e.isPopupTrigger()) {
							popupToPlayerDiscussionTree().show( (JComponent)e.getSource(), e.getX(), e.getY() );
						}
					}
				}
		);
		
        jScrollPaneDiscussion.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPaneDiscussion.setViewportView(jTreeDiscussion);
        
        closeButtonGrpDis.setIcon(new javax.swing.ImageIcon(getClass().getResource("001_05.png"))); // NOI18N
        closeButtonGrpDis.setText("Close");
        closeButtonGrpDis.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeButtonGrpDisActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelDiscussionLayout = new javax.swing.GroupLayout(this);
        this.setLayout(jPanelDiscussionLayout);
        jPanelDiscussionLayout.setHorizontalGroup(
            jPanelDiscussionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelDiscussionLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelDiscussionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelDiscussionLayout.createSequentialGroup()
                        .addComponent(jLabelGrpDis)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabelGrpDisInput, javax.swing.GroupLayout.PREFERRED_SIZE, 157, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabelExplain1)
                    .addComponent(jLabelExplain2)
                    .addComponent(jScrollPaneDiscussion, javax.swing.GroupLayout.PREFERRED_SIZE, 545, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(closeButtonGrpDis, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(30, Short.MAX_VALUE))
        );
        jPanelDiscussionLayout.setVerticalGroup(
            jPanelDiscussionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelDiscussionLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelDiscussionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabelGrpDis)
                    .addComponent(jLabelGrpDisInput))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPaneDiscussion, javax.swing.GroupLayout.PREFERRED_SIZE, 334, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabelExplain1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabelExplain2)
                .addGap(45, 45, 45)
                .addComponent(closeButtonGrpDis)
                .addContainerGap(29, Short.MAX_VALUE))
        );
        
        jPanelDiscussion = this;
	}

	

	/** Add Component Without a Layout Manager (Absolute Positioning) */
	@SuppressWarnings("unused")
	private void addComponent(Container container,Component c,int x,int y,int width,int height)
	{
		c.setBounds(x,y,width,height);
		container.add(c);
	}

	
	
	//
	// TODO: Add any appropriate code in the following Event Handling Methods
	//
//	private void JTreeDiscussion_valueChanged(TreeSelectionEvent e)
//	{
//		System.out.println("\nJTreeDiscussion_valueChanged(TreeSelectionEvent e) called.");
//		DefaultMutableTreeNode node = (DefaultMutableTreeNode)jTreeDiscussion.getLastSelectedPathComponent();
//		if(node == null) return;
//		
//		Object o = node.getUserObject();
//		System.out.println(">>" + ((o==null)? "null" : o.toString()) + " is selected.");
//		// TODO: Add any handling code here for the particular object being selected
//		
//	}

	private void closeButtonGrpDisActionPerformed(java.awt.event.ActionEvent evt) {
		
		JDialog.setDefaultLookAndFeelDecorated(true);
        int response = JOptionPane.showConfirmDialog(null, "Do you really wanna close?", "Confirm close",
        JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
        if (response == JOptionPane.NO_OPTION) {
          
        } else if (response == JOptionPane.YES_OPTION) {
        	asm.sendMessage(new ReleasePlayerDiscussionAgent(), asm.getContext().getParentAddress());
        	mainFrame.getPane().removeTabAt(mainFrame.getPane().getSelectedIndex());
          
        } else if (response == JOptionPane.CLOSED_OPTION) {
        	
        }
	}
	


	public JTree getJTreeGroupDiscussion() {
		if(jTreeDiscussion == null)
		{

			jTreeDiscussion = new JTree(jTreeDiscussionModel);
		}
		return jTreeDiscussion;
	}
	
	private JPopupMenu popupToPlayerDiscussionTree(){
		JPopupMenu popup;
		JMenuItem mi;

		popup = new JPopupMenu();
		mi = new JMenuItem("Insert a comment");
		mi.addActionListener(new PopupListener());
		mi.setActionCommand("insert");
		popup.add(mi);
		mi = new JMenuItem("Edit my comment");
		mi.addActionListener(new PopupListener());
		mi.setActionCommand("edit");
		popup.add(mi);
		popup.setOpaque(true);
		popup.setLightWeightPopupEnabled(true);

		return popup;   	
	}
	
	public void showPopup(String text, int joptionPaneType){
		JOptionPane.showMessageDialog(mainFrame,
			    text,
			    "Message",
			    joptionPaneType);
	}
	
	/**
	 * Update the Discussion Tree when the comment is added
	 */ 
	public void updateDiscussioTreeCommentAddedLocally(Discussion discussion){
        Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		String time = formatter.format(date);
        mainFrame.updateActivityList(time+ ": "+"You posted a new discussion element", "Discussion");
		
		TreePath path = getJTreeGroupDiscussion().getSelectionPath();
		
		DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent();
		
		DefaultMutableTreeNode node = new DefaultMutableTreeNode(discussion);
		dmtn.add(node);
		
		//for refreshing the tree structure
		((DefaultTreeModel )jTreeDiscussionModel).nodeStructureChanged((TreeNode)dmtn);

		//make the node visible by scroll to it
		TreeNode[] nodes = ((DefaultTreeModel )this.jTreeDiscussionModel).getPathToRoot(node);
		path = new TreePath(nodes);
		getJTreeGroupDiscussion().scrollPathToVisible(path);

		//select the newly added node
		getJTreeGroupDiscussion().setSelectionPath(path);

		//TODO send this information to the group agent 
		//TreePath path2 = getJTreeGroupDiscussion()
		System.out.println("Topic to be sent is " + ((Discussion) dmtn.getUserObject() ).getPostedDate());
		System.out.println("Object one sent " + (Object) discussion.toString());
		System.out.println("Object two sent " + dmtn.getUserObject().toString());
		System.out.println("Sending to: "+getGroupDiscussionActorAddress().toString());
		
		XStream xstream = new XStream();
		xstream.setClassLoader(new Discussion().getClass().getClassLoader());
		xstream.alias("discussion", Discussion.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		String xmlDisc = xstream.toXML((Object) discussion);
		String xmlDiscFather = xstream.toXML(dmtn.getUserObject());
		
		System.out.println("XMLDISC I GUI: "+xmlDisc);
		System.out.println("XMLDISCFATHER I GUI"+xmlDiscFather);
		
		asm.sendMessage(new ForwardDiscussionUpdate(xmlDisc, xmlDiscFather), getGroupDiscussionActorAddress());
		
	}

	/**
	 * Update the Discussion Tree when the comment is added by others
	 */ 
	@SuppressWarnings("unchecked")
	public void updateDiscussioTreeCommentAddedByOthers(Discussion discussion, Discussion discFather){
        Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		String time = formatter.format(date);
        mainFrame.updateActivityList(time+ ": "+groupName+" discussion is updated", "Discussion");
		
		
		Enumeration enume = ((DefaultMutableTreeNode)  rootNode).breadthFirstEnumeration();
		DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) rootNode;
		//if ( ((Discussion)((DefaultMutableTreeNode) rootNode).getUserObject())
		//		.getPostedDate().equalsIgnoreCase(discFather.getPostedDate()) ){
		if (enume == null){
			dmtn = (DefaultMutableTreeNode) rootNode;
		}
		else{
			while(enume.hasMoreElements()) {
				
				dmtn = (DefaultMutableTreeNode) enume.nextElement();
				System.out.println("Her kommer forste "+((Discussion)dmtn.getUserObject()).getPostedDate());
				System.out.println("Her kommer andre "+ discFather.getPostedDate());
				System.out.println("Disc to be tested " + ((Discussion)dmtn.getUserObject()).getPostedDate() +
						" and disc father that has been received " + discFather.getPostedDate());
				if( ((Discussion)dmtn.getUserObject()).getPostedDate().equalsIgnoreCase
						(discFather.getPostedDate()) ){
					break;
				}
					
					
			}
		}
		DefaultMutableTreeNode node = new DefaultMutableTreeNode(discussion);
		if (dmtn == null){
			System.out.println("We have a problem at updateDiscussioTreeCommentAddedByOthers");
		}
		else{
			dmtn.add((DefaultMutableTreeNode)node.clone());
		}

		//for refreshing the tree structure
		((DefaultTreeModel )jTreeDiscussionModel).nodeStructureChanged((TreeNode)dmtn);

		//make the node visible by scroll to it
		TreeNode[] nodes = ((DefaultTreeModel )this.jTreeDiscussionModel).getPathToRoot(node);
		TreePath path = new TreePath(nodes);
		getJTreeGroupDiscussion().scrollPathToVisible(path);

		//select the newly added node
		//getJTreeGroupDiscussion().setSelectionPath(path);
		
		
	}
	
	
	public void editDiscussioTreeCommentAddedLocally(String newComment){
        Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		String time = formatter.format(date);
        mainFrame.updateActivityList(time+ ": "+"You edited a discussion post", "Discussion");
		
		
		TreePath path = getJTreeGroupDiscussion().getSelectionPath();
		
		DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent();
		
		((Discussion)dmtn.getUserObject()).setTopicText(newComment);
		
		//for refreshing the tree structure
		((DefaultTreeModel )jTreeDiscussionModel).nodeStructureChanged((TreeNode)dmtn);

		//TODO send this information to the group agent 
		asm.sendMessage(new ForwardDiscussionEdit(dmtn.getUserObject(), newComment), getGroupDiscussionActorAddress());
		
	}
	
	
	@SuppressWarnings("unchecked")
	public void editDiscussioTreeCommentAddedByOthers(Discussion discussion, String newComment){
        Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		String time = formatter.format(date);
        mainFrame.updateActivityList(time+ ": "+groupName+" discussion is edited", "Discussion");
		
		Enumeration enume = ((DefaultMutableTreeNode)  rootNode).breadthFirstEnumeration();
		DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) rootNode;
		//if ( ((Discussion)((DefaultMutableTreeNode) rootNode).getUserObject())
		//		.getPostedDate().equalsIgnoreCase(discFather.getPostedDate()) ){
		if (enume == null){
			dmtn = (DefaultMutableTreeNode) rootNode;
		}
		else{
			while(enume.hasMoreElements()) {
				dmtn = (DefaultMutableTreeNode) enume.nextElement();
				System.out.println("Disc to be tested " + ((Discussion)dmtn.getUserObject()).getPostedDate() +
						" and disc father that has been received " + discussion.getPostedDate());
				if( ((Discussion)dmtn.getUserObject()).getPostedDate().equalsIgnoreCase
						(discussion.getPostedDate()) ){
					break;
				}
					
					
			}
		}
		if (dmtn == null){
			System.out.println("We have a problem at editDiscussioTreeCommentAddedByOthers");
		}
		else{
			((Discussion)dmtn.getUserObject()).setTopicText(newComment);
		}

		//for refreshing the tree structure
		((DefaultTreeModel )jTreeDiscussionModel).nodeStructureChanged((TreeNode)dmtn);
		
	}
	
	public String getPlayerName() {
		return playerName;
	}
	
	public ActorAddress getPlayerActorAddress() {
		return asm.getContext().getParentAddress();
	}
	
	public ActorAddress getGroupDiscussionActorAddress() {
		return groupDiscussionAgentGroup;
	}
	
	public void setJLabelGrpDisInput(String groupName){
		jLabelGrpDisInput.setText(groupName);
	}
	
	
	
	class PopupListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {


			if(e.getActionCommand().endsWith("edit")){
				
				
				
				TreePath path = getJTreeGroupDiscussion().getSelectionPath();
				DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent();
				if (! ((Discussion)dmtn.getUserObject()).getPostedBy().getUserName().equalsIgnoreCase(playerName) ){
					// he is trying to edit someone else comment
					showPopup("You are trying to edit someone else comment", JOptionPane.ERROR_MESSAGE);
				}
				else{
					DiscussionDialog inst = new DiscussionDialog(jPanelDiscussion, getJTreeGroupDiscussion(), false);
					inst.setVisible(true);
				}
			
			}

			if(e.getActionCommand().endsWith("insert")){
				// Open the editing dialog
				DiscussionDialog inst = new DiscussionDialog(jPanelDiscussion, getJTreeGroupDiscussion(), true);
				inst.setVisible(true);
			}
		}
	}



}
